home *** CD-ROM | disk | FTP | other *** search
- /*
- * readnews
- *
- * Michael Rourke (UNSW) April 1984
- */
-
- #include "defs.h"
-
- #define ARTSEP "/"
-
- char admsub[BUFLEN] = "general";
- char dfltsub[BUFLEN] = "general";
- char mailvia[BUFLEN] = "";
- char *mailpath = MAIL;
-
- #define MAXARGV 10 /* used in building argv[]s below */
-
- bool iflag; /* -i ignore .newsrc */
- bool lflag; /* -l print headers only */
- bool cflag; /* -c check for news only */
- bool pflag; /* -p print everything selected */
- bool Cflag; /* -C verbose -c */
- bool sflag; /* -s print newsgroup subscription list */
- bool splus; /* -s+ */
- bool slistall; /* -s? */
- bool sminus; /* -s- */
- char *sarg; /* arg to -s[+-] */
- char *nflag; /* -n newsgroups */
- extern char *rcgrps; /* -n newsgroups from newsrc file */
- bool n_on_cline; /* nflag set on command line */
-
- extern newsrc *rc; /* internal .newsrc */
-
- active *alist; /* internal active list */
-
- #if MANGRPS
- char *mangrps; /* mandatory subsciption list */
- #endif
-
- long now; /* current time */
- bool interrupt; /* if interrupt hit */
- char *newsdir; /* %news */
- bool su; /* if super user (not used) */
-
- applycom list(), check(), commands();
- void *onintr();
- bool ureject(), seen(), subs(), subsub();
-
- #if MANGRPS
- char *getmangrps();
- #endif
-
- char *progname;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char buf[BUFSIZ], *p;
-
- progname = argv[0];
- setbuf(stdout, buf);
- if (options(--argc, ++argv, true)) {
- (void) fprintf(stderr, "Usage: readnews [-n newsgroups] [-i] [-clpC] [-s[-+? [group]]]\n");
- exit(1);
- }
- now = time(&now);
-
- newsdir = newstr(fullartfile((char *)NULL));
- getctl();
-
- if (!iflag)
- readnewsrc();
-
- if (nflag)
- convgrps(nflag);
- else
- nflag = dfltsub;
- if (rcgrps)
- convgrps(rcgrps);
- if (!n_on_cline) {
- #if MANGRPS
- int addsub();
-
- if (mangrps = getmangrps(pe.pw_cmask))
- applyng(mangrps, addsub, &nflag);
- #endif
- if (!ngmatch(admsub, nflag))
- nflag = newstr3(admsub, NGSEPS, nflag);
- }
- if ((int) sflag + (int) lflag + (int) cflag + (int) pflag > 1)
- error("-clpsC flags are mutually exclusive.");
-
- /* user has private mailer? */
- if ((p = getenv("MAILER")) != NULL)
- mailpath = newstr(p);
-
- alist = readactive();
-
- if (sflag) {
- if (subs() && !iflag)
- writenewsrc(alist);
- } else if (lflag)
- apply(alist, nflag, list, false);
- else if (cflag)
- apply(alist, nflag, check, false);
- else {
- if (!pflag) {
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- (void) signal(SIGINT, onintr);
- if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- (void) signal(SIGQUIT, onintr);
- }
- apply(alist, nflag, commands, true);
- if (!iflag)
- writenewsrc(alist);
- }
- fflush(stdout);
- exit(0);
- }
-
- #if MANGRPS
- /*
- * make a subscription list of all class groups the user belongs too
- * (mandatory subscription)
- */
- char *
- getmangrps(cmask)
- char *cmask;
- {
- static char *weekday[] = {
- "mon", "tue", "wed", "thu", "fri" };
- register char **classes;
- register char *s, *end;
- register char *grp;
- register int i, size;
- extern char **getclasses();
-
- grp = NIL(char);
- if ((classes = getclasses(cmask)) == NIL(char *))
- error("Can't get classes.");
- while (*classes) {
- if (isdigit(**classes)) {
- /*
- * trim string after numeric class
- * if it is a day of the week
- */
- s = *classes;
- while (isdigit(*s) || *s == '.')
- s++;
- if (*s) {
- end = s;
- while (isalpha(*end))
- end++;
- if (*end && end != s && end - s <= 3) {
- size = end - s;
- for (i = 0; i < 5; i++)
- if (CMPN(s, weekday[i], size) == 0)
- break;
- if (i != 5)
- *s = '\0';
- }
- }
- }
- grp = (grp? catstr2(grp, ",class.", *classes):
- newstr2("class.", *classes));
- classes++;
- }
- return grp;
- }
-
- /*
- * if newsgroup "ng" isn't subscribed to, add it to subscription list
- */
- addsub(ng, slist)
- char *ng;
- char **slist;
- {
- if (!ngmatch(ng, *slist))
- *slist = newstr3(ng, NGSEPS, *slist);
- }
-
- #endif
-
- void *
- onintr()
- {
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- (void) signal(SIGINT, onintr);
- if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- (void) signal(SIGQUIT, onintr);
- interrupt = true;
- }
-
- /*
- * process options
- * can be called from readnewsrc()
- */
- options(argc, argv, cline)
- int argc;
- char *argv[];
- bool cline;
- {
- register char c;
-
- /* TODO: use getopt(3) */
- while (argc > 0) {
- if (argv[0][0] != '-')
- break;
- while (c = *(++(argv[0]))) {
- switch (c) {
- case 'n':
- if (cline)
- nflag = argv[1], n_on_cline = true;
- else {
- if (!n_on_cline)
- nflag = (nflag?
- catstr2(nflag, NGSEPS, argv[1]):
- newstr(argv[1]));
- rcgrps = (rcgrps?
- catstr2(rcgrps, NGSEPS, argv[1]):
- newstr(argv[1]));
- }
- argc--, argv++;
- break;
- case 'i':
- iflag = true;
- continue;
- case 's':
- sflag = true;
- switch (argv[0][1]) {
- case '\0':
- continue;
- case '+':
- splus = true;
- break;
- case '?':
- slistall = true, ++(argv[0]);
- continue;
- case '-':
- sminus = true;
- break;
- default:
- argc = -1;
- break;
- }
- if (argc > 0) {
- sarg = newstr(argv[1]);
- argc--, argv++;
- }
- break;
- case 'p':
- pflag = true;
- continue;
- case 'l':
- lflag = true;
- continue;
- case 'c':
- cflag = true;
- continue;
- case 'C':
- cflag = Cflag = true;
- continue;
- default:
- argc = -1;
- break;
- }
- break;
- }
- argc--, argv++;
- }
- return argc != 0;
- }
-
- /*
- * subscription list handling
- * return true if newsrc is to be re-written
- */
- bool
- subs()
- {
- register newsrc *np;
- register active *ap;
- register char *tmp, *com;
- register FILE *f;
-
- if (slistall) {
- (void) printf("Active newsgroups:\n");
- (void) fflush(stdout);
- /* possibly vestigial code here, old #ifdefs deleted */
- f = stdout;
- com = 0; /* for lint */
- com = com; /* for lint */
- for (ap = alist; ap; ap = ap->a_next)
- (void) fprintf(f, "%s\n", ap->a_name);
- return false;
- } else if (splus || sminus) {
- if (strpbrk(sarg, BADGRPCHARS)) {
- (void) printf("%s: Illegal char in newsgroup.\n", sarg);
- return false;
- }
- if (ngmatch(sarg, nflag)) {
- /*
- * normally we subscribe, check for an exclusion
- */
- for (np = rc; np; np = np->n_next)
- if (CMP(sarg, np->n_name) == 0)
- break;
- if (np) {
- /*
- * altering subscribe flag is all
- * we need to change
- */
- np->n_subscribe = splus;
- return true;
- }
- if (sminus) {
- /*
- * try deleting from sub list
- */
- if (subsub(sarg, rcgrps))
- return true;
- /*
- * add specific exclusion
- */
- rcgrps = newstr4(rcgrps, NGSEPS, NEGS, sarg);
- return true;
- }
- } else if (splus) {
- /*
- * we don't subscribe,
- * try deleting !sarg first
- */
- tmp = newstr2(NEGS, sarg);
- subsub(tmp, rcgrps);
- if (!ngmatch(sarg, rcgrps))
- /*
- * didn't work, so add explicit subscription
- */
- rcgrps = rcgrps? newstr3(rcgrps, NGSEPS, sarg):
- newstr(sarg);
- return true;
- }
- } else {
- (void) printf("Subscription list: %s", nflag);
- for (np = rc; np; np = np->n_next)
- if (!np->n_subscribe && ngmatch(np->n_name, nflag))
- (void) printf(",!%s", np->n_name);
- (void) printf("\n");
- }
- return false;
- }
-
-
- /*
- * try and delete group from subscription list
- * return true if successful
- */
- bool
- subsub(grp, slist)
- char *grp;
- char *slist;
- {
- register char *delim;
-
- while (*slist) {
- if (delim = strchr(slist, NGSEPCHAR))
- *delim = '\0';
- if (CMP(grp, slist) == 0) {
- if (delim)
- (void) strcpy(slist, delim + 1);
- else if (slist[-1] == ',')
- slist[-1] = '\0';
- else
- slist[0] = '\0';
- return true;
- }
- if (delim)
- *delim = NGSEPCHAR, slist = delim + 1;
- else
- break;
- }
- return false;
- }
-
- char *
- ltoa(l)
- long l;
- {
- static char buf[30];
-
- sprintf(buf, "%ld", l);
- return buf;
- }
-
- /*
- * list titles command (-l)
- */
- applycom
- list(ap, np)
- active *ap;
- newsrc *np;
- {
- static active *lastap;
- static bool first = true;
- register char *fname;
- register FILE *f;
- header h;
- ino_t ino;
-
- np->n_last++;
- fname = convg(newstr5(newsdir, "/", ap->a_name, ARTSEP,
- ltoa(np->n_last)));
- ino = 0;
- f = fopen(fname, "r");
- free(fname);
- if (!f || seen(f, &ino))
- return next;
- gethead(f, &h);
- if (first) {
- (void) printf("News articles:\n");
- first = false;
- }
- if (lastap != ap)
- (void) printf(" %s:\n", ap->a_name);
- lastap = ap;
- (void) printf(" %-4d %s\n", np->n_last, h.h_subject);
- (void) fclose(f);
- freehead(&h);
- if (ino)
- seen(NIL(FILE), &ino);
- return next;
- }
-
- /*
- * check command (-c or -C)
- */
- applycom
- check(ap, np)
- active *ap;
- newsrc *np;
- {
- static bool done;
-
- np->n_last++;
- if (Cflag) {
- register long num;
-
- if (!done)
- (void) printf("You have news:\n");
- done = true;
- num = ap->a_seq - np->n_last + 1;
- (void) printf("\t%s at most %ld article%s\n",
- ap->a_name, num, (num > 1? "s": ""));
- return nextgroup;
- } else {
- (void) printf("You have news.\n");
- fflush(stdout);
- exit(0);
- /* NOTREACHED */
- }
- }
-
- /*
- * normal command handler (or pflag)
- * commands:
- *
- * \n print current article
- * n go to next article
- * q quit
- * r reply
- * f followup
- * p postnews
- * N [newsgrp] next newsgroup
- * s [file] save
- * U unsubscribe from group
- * !stuff shell escape
- * number or . go to number
- * - back to previous article (toggle)
- * x quick exit
- * h long header info
- * H full header
- *
- * inside r, f or p:
- * .e edit
- * .i interpolate
- * . or EOT terminate message
- * .!comd shell escape
- */
- applycom
- commands(ap, np, last, pushed)
- active *ap;
- newsrc *np;
- bool last;
- bool pushed;
- {
- register char *com, *arg;
- register int c, size;
- register long i;
- register FILE *f;
- char *fname;
- header h;
- newsrc ntmp;
- ino_t ino;
- bool printed, pheader, verbose, hadinterrupt;
- applycom nextact;
- static char errmess[] = "Unknown command; type `?' for help.\n";
- static char form[] = "%s: %s\n";
- static char savedsys[BUFSIZ / 2];
- static active *lastap, *rlastap;
- static newsrc lastn;
- static char number[20];
- static active *wantap;
- extern char t_from[], t_subject[], t_date[];
- extern char t_newsgroups[], t_path[], t_sender[];
- extern char t_replyto[], t_organization[];
- extern active *activep();
-
- if (last) {
- /*
- * give user one last chance to
- * see this article
- */
- ap = rlastap;
- np = &lastn;
- wantap = NIL(active);
- if (!ap || pflag)
- return stop;
- } else if (wantap)
- /*
- * doing an "n newsgroup" command
- */
- if (wantap != ap)
- return nextgroup;
- else
- wantap = NULL;
-
- fname = convg(newstr5(newsdir, "/", ap->a_name, ARTSEP,
- ltoa(np->n_last + 1)));
- f = fopen(fname, "r");
- ino = 0;
- if (!f || !last && !pushed && seen(f, &ino)) {
- if (pushed)
- (void) printf("Article %ld (%s) no longer exists.\n",
- np->n_last + 1, ap->a_name);
- else
- np->n_last++;
- if (f)
- (void) fclose(f);
- free(fname);
- return next;
- }
-
- gethead(f, &h);
-
- (void) printf("\n");
- interrupt = hadinterrupt = verbose = false;
- if (last) {
- (void) printf("No more articles (press RETURN again to quit).\n");
- printed = pheader = true;
- } else
- printed = pheader = false;
-
- while (1) {
- if (lastap != ap) {
- size = strlen(ap->a_name) + sizeof("Newsgroup");
- for (i = 0; i < size; i++)
- (void) putc('-', stdout);
- (void) printf("\nNewsgroup %s\n", ap->a_name);
- for (i = 0; i < size; i++)
- (void) putc('-', stdout);
- (void) printf("\n\n");
- }
- lastap = ap;
- if (!pheader) {
- time_t itsdate;
- (void) printf("Article %ld of %ld (%s)",
- np->n_last + 1, ap->a_seq, ap->a_name);
- if (h.h_lines != 0)
- (void) printf(" (%s lines)", h.h_lines);
- if (h.h_date != NULL) {
- itsdate = atot(h.h_date);
- (void) printf(" %s", ctime(&itsdate));
- } else
- (void) printf(" %s", "<no date!>\n");
- (void) printf(form, t_subject, h.h_subject);
- (void) printf(form, t_from, h.h_from);
- if (verbose || pflag) {
- (void) printf(form, t_date, h.h_date);
- (void) printf(form, t_newsgroups, h.h_newsgroups);
- (void) printf(form, t_path, h.h_path);
- if (h.h_sender)
- (void) printf(form, t_sender, h.h_sender);
- if (h.h_replyto)
- (void) printf(form, t_replyto, h.h_replyto);
- if (h.h_organisation)
- (void) printf(form, t_organization, h.h_organisation);
- verbose = false;
- }
- pheader = true;
- }
- if (!pushed && number[0])
- /*
- * just returned from a number command
- * and have another to do
- */
- com = number;
- else if (pflag)
- /*
- * just print it
- */
- com = "";
- else {
- (void) printf("? ");
- if (fflush(stdout) == EOF) {
- (void) printf("\n? ");
- (void) fflush(stdout);
- }
- interrupt = false;
- if ((com = mgets()) == NIL(char)) {
- if (interrupt)
- if (!hadinterrupt) {
- clearerr(stdin);
- (void) printf("Interrupt\n");
- hadinterrupt = true;
- interrupt = false;
- continue;
- }
- else
- exit(1);
- nextact = stop;
- break;
- }
- hadinterrupt = false;
- }
- if (*com == '!') {
- if (com[1] == '!') {
- (void) printf("!%s\n", savedsys);
- com = savedsys;
- } else
- com++;
- (void) fflush(stdout);
- #ifdef F_SETFD
- (void) fcntl(fileno(f), F_SETFD, 1); /* close on exec */
- #endif
- (void) system(com);
- if (com != savedsys)
- strncpy(savedsys, com, sizeof(savedsys) - 1);
- (void) printf("!\n");
- if (!printed)
- pheader = false;
- continue;
- }
- /*
- * check command syntax
- */
- if (*com && !isdigit(*com) && com[1] && (!isspace(com[1]) ||
- strchr("Nsm", *com) == NULL)) {
- (void) printf(errmess);
- continue;
- }
- if (c = *com) {
- arg = com;
- while (isspace(*++arg))
- ;
- } else
- arg = NULL;
- switch (c) {
- case 0:
- case '.':
- if (!printed || c == '.') {
- if (pflag)
- (void) printf("\n");
- print(&h, f);
- if (pflag) {
- nextact = next;
- break;
- }
- printed = true;
- continue;
- }
- case 'n': /* B compatible */
- case '+':
- case ';':
- nextact = next;
- break;
- case '?':
- help();
- continue;
- case 'r':
- reply(&h, fname);
- continue;
- case 'f':
- followup(&h, fname);
- continue;
- case 'p':
- pnews(ap->a_name);
- continue;
- case 'U':
- if (ngmatch(np->n_name, admsub)
- #if MANGRPS
- || ngmatch(np->n_name, mangrps))
- #else
- )
- #endif
- {
- (void) printf(
- "Group \"%s\" can't be unsubscribed.\n",
- np->n_name);
- continue;
- }
- np->n_subscribe = false;
- nextact = nextgroup;
- break;
- case 'N': /* B compatible */
- if (!*arg) {
- nextact = nextgroup;
- break;
- }
- if ((wantap = activep(arg)) == NIL(active)) {
- (void) printf("%s: non-existent newsgroup.\n", arg);
- continue;
- }
- if (!ngmatch(arg, nflag)) {
- (void) printf("%s: is not subscribed to!\n", arg);
- wantap = NULL;
- continue;
- }
- nextact = searchgroup;
- break;
- case 's':
- save(&h, f, arg);
- continue;
- case 'q':
- nextact = stop;
- break;
- case 'x':
- fflush(stdout);
- exit(0);
- case 'h':
- verbose = true;
- pheader = false;
- continue;
- case 'H':
- puthead(&h, stdout, printing);
- continue;
- case '-':
- if (pushed) {
- nextact = next;
- break;
- }
- if (!rlastap || !lastn.n_name) {
- (void) printf("Can't go back!\n");
- continue;
- }
- nextact = commands(rlastap, &lastn, false, true);
- /*
- * number commands, after a "-" act on the
- * group of the "-" command
- */
- while (number[0]) {
- ntmp = lastn;
- ntmp.n_last = atol(number) - 1;
- number[0] = '\0';
- nextact = commands(rlastap, &ntmp, false, true);
- }
- if (nextact != next)
- break;
- (void) printf("\n");
- pheader = false;
- continue;
- default:
- if (isdigit(c)) {
- /* i = atol(arg); */
- i = c - '0';
- while (isdigit(*arg))
- i = i * 10 + *arg++ - '0';
- }
- if (!isdigit(c) || *arg != '\0') {
- (void) printf(errmess);
- continue;
- }
- number[0] = '\0';
- if (i < ap->a_low || i > ap->a_seq) {
- (void) printf(
- "Articles in \"%s\" group range %ld to %ld.\n",
- np->n_name, ap->a_low, ap->a_seq);
- continue;
- }
- if (pushed) {
- sprintf(number, "%ld", i);
- nextact = next;
- break;
- }
- ntmp = *np;
- ntmp.n_last = i - 1;
- if ((nextact = commands(ap, &ntmp, false, true)) != next)
- break;
- if (!number[0]) {
- (void) printf("\n");
- pheader = false;
- }
- continue;
- }
- break;
- }
- rlastap = ap;
- lastn = *np;
- if (!pushed && (nextact == next || printed)) {
- np->n_last++;
- if (ino)
- seen(NIL(FILE), &ino);
- }
- freehead(&h);
- (void) fclose(f);
- free(fname);
- return nextact;
- }
-
-
- /*
- * see if the article has links, if so have we seen it?
- * close file if we return true
- *
- * called twice,
- * first (with f set) to test (and possibly set *ino)
- * again to put *ino in memory
- */
- bool
- seen(f, ino)
- FILE *f;
- ino_t *ino;
- {
- static int num;
- static ino_t *ilist;
- struct stat statb;
- register int i;
-
- if (f) {
- if (fstat(fileno(f), &statb) != 0 || statb.st_nlink <= 1)
- return false;
- for (i = 0; i < num; i++)
- if (ilist[i] == statb.st_ino) {
- (void) fclose(f);
- return true;
- }
- *ino = statb.st_ino;
- return false;
- } else if (*ino) {
- num++;
- ilist = (ino_t * ) (ilist ? myrealloc((char *) ilist, (int) sizeof(ino_t) *
- num) : myalloc((int) sizeof(ino_t)));
- ilist[num - 1] = *ino;
- }
- return true;
- }
-
-
- /*
- * print out help file
- */
- help()
- {
- register FILE *f;
- register int c;
- register char *helppath;
-
- helppath = ctlfile("readnews.help");
- if ((f = fopen(helppath, "r")) == NIL(FILE)) {
- (void) printf("Can't open %s\n", helppath);
- return;
- }
- while ((c = getc(f)) != EOF)
- (void) putc(c, stdout);
- (void) fclose(f);
- }
-
- /*
- * reply to sender by mail
- */
- /* ARGSUSED fname */
- reply(hp, fname)
- header *hp;
- char *fname;
- {
- char *argv[MAXARGV];
- register int argc;
-
- argc = 0;
- argv[argc++] = "mail";
- #ifdef UNSWMAIL
- argv[argc++] = "-s";
- if ((argv[argc++] = getsubject(hp)) == NIL(char))
- return;
- argv[argc++] = "-i";
- argv[argc++] = fname;
- #endif
-
- if ((argv[argc++] = getretaddr(hp)) == NIL(char)) {
- (void) printf("Can't work out an address!\n");
- return;
- }
-
- argv[argc++] = NIL(char);
-
- run(mailpath, argv, false);
-
- free(argv[argc - 2]);
- }
-
-
-
- /*
- * generate correct headers for a followup article
- * then call postnews.
- */
- followup(hp, fname)
- header *hp;
- char *fname;
- {
- char tmpf[50];
- register FILE *fo;
- char *s = getsubject(hp);
-
- if (s == NULL)
- return;
- (void) strcpy(tmpf, "/tmp/rfXXXXXX");
- (void) mktemp(tmpf);
- fo = fopen(tmpf, "w");
- if (fo == NULL)
- error("can't create `%s'", tmpf);
- fprintf(fo, "Newsgroups: %s\n", (hp->h_followupto) ? hp->h_followupto :
- hp->h_newsgroups);
- fprintf(fo, "Subject: %s\n", s);
- free(s);
- if (hp->h_references && hp->h_messageid)
- fprintf(fo, "References: %s %s\n", hp->h_references, hp->h_messageid);
- else if (hp->h_messageid)
- fprintf(fo, "References: %s\n", hp->h_messageid);
- (void) fclose(fo);
-
- s = newstr3(binfile("inject/postnews"), " -h ", tmpf);
- system(s);
- free(s);
-
- (void) unlink(tmpf);
- }
-
- /*
- * get correct "Subject: Re: .." line
- */
- char *
- getsubject(hp)
- register header *hp;
- {
- register char *s;
-
- if (!hp->h_subject) {
- (void) printf("Subject: Re: ");
- (void) fflush(stdout);
- if ((s = mgets()) == NIL(char) || !*s) {
- (void) printf("The Subject field is mandatory.\n");
- return NIL(char);
- }
- return newstr2("Re: ", s);
- } else if (CMPN(hp->h_subject, "Re: ", 4) != 0 && CMPN(hp->h_subject,
- "re: ", 4) != 0)
- return newstr2("Re: ", hp->h_subject);
- else
- return newstr(hp->h_subject);
- }
-
-
- /*
- * run a command, optionally closing stdin
- */
- run(com, argv, closein)
- char *com;
- char *argv[];
- bool closein;
- {
- int pid, status, r;
-
- switch (pid = fork()) {
- default:
- /* parent */
- break;
- case 0:
- /* child */
- if (closein)
- close(fileno(stdin));
- execvp(com, argv);
- error("can't exec %s", com);
- exit(1);
-
- case -1:
- error("can't fork");
- }
-
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- (void) signal(SIGINT, SIG_IGN);
- if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- (void) signal(SIGQUIT, SIG_IGN);
-
- while ((r = wait(&status)) != pid && r != -1)
- ;
-
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- (void) signal(SIGINT, onintr);
- if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- (void) signal(SIGQUIT, onintr);
- }
-
- /*
- * call postnews
- */
- pnews(group)
- char *group;
- {
- register char *s = newstr3(binfile("inject/postnews"), " ", group);
- system(s);
- free(s);
- }
-
- /*
- * save an article
- */
- save(hp, f, s)
- header *hp;
- FILE *f;
- char *s;
- {
- register long pos;
- register int c;
- register char *cp;
- register FILE *sf;
- register char *aname;
- long then;
- extern char *getenv();
-
- if (!*s) {
- if ((aname = getenv("HOME")) == NIL(char)) {
- (void) printf("No $HOME in environment.\n");
- return;
- }
- s = aname = newstr3(aname, "/", ARTICLES);
- } else
- aname = NIL(char);
- if ((sf = fopen(s, "a")) == NIL(FILE)) {
- (void) fprintf(stderr, "readnews: can't open %s\n", s);
- return;
- }
- if (aname)
- free(aname);
- pos = ftell(f);
- rewind(f);
- if (cp = strchr(hp->h_from, ' '))
- *cp = '\0';
- if (hp->h_date)
- then = atot(hp->h_date);
- else
- then = 0L;
- (void) fprintf(sf, "From %s %s", hp->h_from, ctime(then ? &then : &now));
- if (cp)
- *cp = ' ';
- while ((c = getc(f)) != EOF)
- (void) putc(c, sf);
- (void) putc('\n', sf);
- (void) fclose(sf);
- fseek(f, pos, 0);
- }
-
-
-
- /*
- * print an article, if it's long enough call page()
- */
- /* ARGSUSED */
- print(hp, f)
- header *hp;
- FILE *f;
- {
- register int c;
- register long pos;
-
- pos = ftell(f);
- if (!pflag)
- page(f);
- else
- while ((c = getc(f)) != EOF)
- (void) putchar(c);
- (void) fseek(f, pos, 0);
- }
-
-
- /*
- * copy article text to stdout, and break into pages
- */
- page(f)
- FILE *f;
- {
- register int c;
- register unsigned lineno;
- char lbuf[80];
-
- lineno = 1;
- while (!interrupt) {
- for (; lineno < PAGESIZE - 4 && !interrupt; lineno++) {
- while ((c = getc(f)) != EOF && c != '\n')
- (void) putchar(c);
- if (c == EOF)
- goto fastexit;
- if (lineno < PAGESIZE - 5)
- (void) putchar('\n');
- }
- if (interrupt)
- break;
- if (fflush(stdout) == EOF)
- break;
- if (read(fileno(stdin), lbuf, sizeof(lbuf)) <= 0)
- break;
- lineno = 0;
- }
- if (lineno)
- (void) putchar('\n');
- interrupt = false;
- fastexit: ;
- }
-
- /* VARARGS1 */
- error(s, a0, a1, a2, a3)
- char *s;
- {
- (void) fprintf(stderr, "readnews: ");
- (void) fprintf(stderr, s, a0, a1, a2, a3);
- (void) fprintf(stderr, "\n");
- fflush(stdout); /* just on principle */
- exit(1);
- }
-
- /*
- - unprivileged - no-op needed to keep the pathname stuff happy
- */
- void
- unprivileged(reason)
- char *reason;
- {
- }
-
- /*
- - getctl - pick up control file for subscriptions etc.
- */
- getctl()
- {
- register FILE *f;
- register char *fname;
- char line[BUFLEN];
- register char *p;
-
- fname = ctlfile("readnews.ctl");
- f = fopen(fname, "r");
- if (f == NULL)
- return;
-
- while (fgets(line, sizeof(line), f) != NULL) {
- line[strlen(line)-1] = '\0'; /* dispose of newline */
- p = strchr(line, '\t');
- if (p == NULL)
- p = strchr(line, ' ');
- if (line[0] != '#' && p != NULL) {
- while (*p == ' ' || *p == '\t')
- *p++ = '\0';
- if (strcmp(line, "defsub") == 0)
- (void) strcpy(dfltsub, p);
- else if (strcmp(line, "mustsub") == 0)
- (void) strcpy(admsub, p);
- else if (strcmp(line, "mailvia") == 0)
- (void) strcpy(mailvia, p);
- }
- }
-
- (void) fclose(f);
- }
-